// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   TagParser.java

package com.java4less.rchart.tags;

import java.io.PrintStream;
import java.util.Vector;

// Referenced classes of package com.java4less.rchart.tags:
//			TagObject

public class TagParser
{

	static final int T_TAG_DELIMITER = 0;
	static final int T_STRING = 1;
	static final int T_EQUALS = 2;
	static final int T_LF = 3;
	static final int T_CR = 4;
	static final int T_BACKSPACE = 5;
	static final int T_END = 6;
	int items[];
	String values[];
	int counter;
	int currentItem;
	int currentPos;
	String currentValue;

	public TagParser()
	{
		items = new int[100];
		values = new String[100];
		counter = 0;
		currentItem = 0;
		currentPos = 0;
	}

	private void parseObject(TagObject object)
	{
		nextToken();
		if (currentItem != 1)
		{
			reportError("Object name expected");
			return;
		}
		object.setAttribute(TagObject.ATT_OBJECT_NAME, currentValue);
		nextToken();
		do
		{
			if (currentItem == 6)
				break;
			switch (currentItem)
			{
			case 1: // '\001'
				parseAttribute(object);
				nextToken();
				break;

			case 0: // '\0'
				nextToken();
				return;
			}
		} while (true);
	}

	private void parseAttribute(TagObject object)
	{
		String attName = currentValue.toUpperCase();
		nextToken();
		if (currentItem != 2)
		{
			reportError("Sign = expected after attribute name");
			return;
		}
		nextToken();
		if (currentItem != 1)
		{
			reportError("Value for attribute expected");
			return;
		} else
		{
			object.setAttribute(attName, currentValue);
			return;
		}
	}

	private void reportError(String s)
	{
		System.err.println(s);
	}

	private void nextToken()
	{
		if (currentPos >= counter)
		{
			currentValue = "";
			currentItem = 6;
			return;
		} else
		{
			currentValue = values[currentPos];
			currentItem = items[currentPos++];
			return;
		}
	}

	public TagObject[] parseTags(String tags)
	{
		tokenize(tags);
		Vector tagsVector = new Vector();
		currentPos = 0;
		nextToken();
		do
		{
			if (currentItem == 6)
				break;
			switch (currentItem)
			{
			case 0: // '\0'
				TagObject object = new TagObject(TagObject.TAG_OBJECT, currentValue);
				tagsVector.addElement(object);
				parseObject(object);
				break;

			case 1: // '\001'
				tagsVector.addElement(new TagObject(TagObject.TAG_STRING, currentValue));
				nextToken();
				break;

			case 3: // '\003'
				tagsVector.addElement(new TagObject(TagObject.TAG_LF));
				nextToken();
				break;

			case 4: // '\004'
				tagsVector.addElement(new TagObject(TagObject.TAG_CR));
				nextToken();
				break;

			case 5: // '\005'
				tagsVector.addElement(new TagObject(TagObject.TAG_BACKSPACE));
				nextToken();
				break;

			case 2: // '\002'
			default:
				nextToken();
				break;
			}
		} while (true);
		TagObject result[] = new TagObject[tagsVector.size()];
		for (int i = 0; i < result.length; i++)
			result[i] = (TagObject)tagsVector.elementAt(i);

		return result;
	}

	private void addItem(String currentItem)
	{
		if (currentItem.length() > 0)
		{
			values[counter] = currentItem;
			items[counter++] = 1;
		}
	}

	private void tokenize(String s)
	{
		boolean inQuotes = false;
		boolean inObject = false;
		boolean inEscape = false;
		int timetout = 0;
		counter = 0;
		int i = 0;
		char c = ' ';
		char escapeChar = '\\';
		String currentItem = "";
		boolean endOfString = i >= s.length();
		boolean done = false;
		do
		{
			if (endOfString || ++timetout > 1000)
				break;
			inEscape = false;
			endOfString = i >= s.length();
			if (endOfString)
				break;
			c = ' ';
			if (!endOfString)
				c = s.charAt(i);
			done = false;
			if (c == escapeChar)
				if (i + 1 < s.length())
				{
					i++;
					c = s.charAt(i);
					inEscape = true;
				} else
				{
					c = ' ';
					endOfString = true;
				}
			if (inQuotes)
			{
				if (!endOfString && (c != '\'' || inEscape))
					currentItem = (new StringBuilder()).append(currentItem).append(c).toString();
				if (c == '\'' && !inEscape || endOfString)
				{
					inQuotes = false;
					values[counter] = currentItem;
					items[counter++] = 1;
					currentItem = "";
				}
				done = true;
			} else
			if (inObject)
			{
				if (c == '@')
				{
					items[counter++] = 0;
					done = true;
					inObject = false;
				} else
				if (c == '=')
				{
					addItem(currentItem);
					currentItem = "";
					items[counter++] = 2;
					done = true;
				} else
				if (c == '\'')
				{
					addItem(currentItem);
					currentItem = "";
					inQuotes = true;
					done = true;
				} else
				if (c == ' ')
				{
					addItem(currentItem);
					currentItem = "";
					done = true;
				} else
				{
					currentItem = (new StringBuilder()).append(currentItem).append(c).toString();
					done = true;
				}
			} else
			if (c == '@' && !inEscape)
			{
				addItem(currentItem);
				currentItem = "";
				items[counter++] = 0;
				inObject = true;
				done = true;
			} else
			if (inEscape && c == 'n')
			{
				addItem(currentItem);
				currentItem = "";
				items[counter++] = 3;
				done = true;
			} else
			if (inEscape && c == 'b')
			{
				addItem(currentItem);
				currentItem = "";
				items[counter++] = 5;
				done = true;
			} else
			if (inEscape && c == 'r')
			{
				addItem(currentItem);
				currentItem = "";
				items[counter++] = 4;
				done = true;
			} else
			{
				currentItem = (new StringBuilder()).append(currentItem).append(c).toString();
				done = true;
			}
			if (done)
			{
				i++;
				c = ' ';
			}
		} while (!endOfString);
		addItem(currentItem);
		items[counter++] = 6;
	}
}
